package org.jivesoftware.smackx.filetransfer;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.jivesoftware.smack.Connection;
import org.jivesoftware.smack.PacketCollector;
import org.jivesoftware.smack.SmackConfiguration;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.filter.PacketIDFilter;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.IQ.Type;
import org.jivesoftware.smack.util.Cache;
import org.jivesoftware.smackx.ServiceDiscoveryManager;
import org.jivesoftware.smackx.packet.Bytestream;
import org.jivesoftware.smackx.packet.Bytestream.StreamHost;
import org.jivesoftware.smackx.packet.DiscoverInfo;
import org.jivesoftware.smackx.packet.DiscoverInfo.Identity;
import org.jivesoftware.smackx.packet.DiscoverItems;
import org.jivesoftware.smackx.packet.DiscoverItems.Item;

public class Socks5TransferNegotiatorManager
  implements FileTransferNegotiatorManager
{
  private static final long BLACKLIST_LIFETIME = 7200000L;
  private static ProxyProcess proxyProcess;
  private final Cache<String, Integer> addressBlacklist;
  private Connection connection;
  private final Object processLock;
  private List<String> proxies;
  private final Object proxyLock = new Object();
  private List<Bytestream.StreamHost> streamHosts;

  public Socks5TransferNegotiatorManager(Connection paramConnection)
  {
    this.processLock = new Object();
    this.addressBlacklist = new Cache(100, 7200000L);
    this.connection = paramConnection;
  }

  private String checkIsProxy(ServiceDiscoveryManager paramServiceDiscoveryManager, DiscoverItems.Item paramItem)
  {
    String str;
    DiscoverInfo localDiscoverInfo;
    Iterator localIterator;
    try
    {
      localDiscoverInfo = paramServiceDiscoveryManager.discoverInfo(paramItem.getEntityID());
      localIterator = localDiscoverInfo.getIdentities();
      if (!(localIterator.hasNext()))
      {
        str = null;
        return str;
      }
    }
    catch (XMPPException localXMPPException)
    {
      DiscoverInfo.Identity localIdentity;
      do
      {
        while (true)
          str = null;
        localIdentity = (DiscoverInfo.Identity)localIterator.next();
      }
      while ((!("proxy".equalsIgnoreCase(localIdentity.getCategory()))) || (!("bytestreams".equalsIgnoreCase(localIdentity.getType()))));
      str = localDiscoverInfo.getFrom();
    }
  }

  private void initProxies()
  {
    this.proxies = new ArrayList();
    ServiceDiscoveryManager localServiceDiscoveryManager = ServiceDiscoveryManager.getInstanceFor(this.connection);
    try
    {
      label63: String str;
      Iterator localIterator = localServiceDiscoveryManager.discoverItems(this.connection.getServiceName()).getItems();
      do
      {
        boolean bool = localIterator.hasNext();
        if (!(bool))
        {
          if (this.proxies.size() > 0)
            initStreamHosts();
          return;
        }
        str = checkIsProxy(localServiceDiscoveryManager, (DiscoverItems.Item)localIterator.next());
      }
      while (str == null);
      this.proxies.add(str);
    }
    catch (XMPPException localXMPPException)
    {
      break label63:
    }
  }

  private void initStreamHosts()
  {
    ArrayList localArrayList = new ArrayList();
    Iterator localIterator = this.proxies.iterator();
    while (true)
    {
      if (!(localIterator.hasNext()))
      {
        this.streamHosts = localArrayList;
        return;
      }
      String str = (String)localIterator.next();
      1 local1 = new IQ(this)
      {
        public String getChildElementXML()
        {
          return "<query xmlns=\"http://jabber.org/protocol/bytestreams\"/>";
        }
      };
      local1.setType(IQ.Type.GET);
      local1.setTo(str);
      PacketCollector localPacketCollector = this.connection.createPacketCollector(new PacketIDFilter(local1.getPacketID()));
      this.connection.sendPacket(local1);
      Bytestream localBytestream = (Bytestream)localPacketCollector.nextResult(SmackConfiguration.getPacketReplyTimeout());
      if (localBytestream != null)
        localArrayList.addAll(localBytestream.getStreamHosts());
      localPacketCollector.cancel();
    }
  }

  // ERROR //
  public ProxyProcess addTransfer()
    throws IOException
  {
    // Byte code:
    //   0: aload_0
    //   1: getfield 39	org/jivesoftware/smackx/filetransfer/Socks5TransferNegotiatorManager:processLock	Ljava/lang/Object;
    //   4: astore_1
    //   5: aload_1
    //   6: monitorenter
    //   7: getstatic 209	org/jivesoftware/smackx/filetransfer/Socks5TransferNegotiatorManager:proxyProcess	Lorg/jivesoftware/smackx/filetransfer/Socks5TransferNegotiatorManager$ProxyProcess;
    //   10: ifnonnull +30 -> 40
    //   13: new 10	org/jivesoftware/smackx/filetransfer/Socks5TransferNegotiatorManager$ProxyProcess
    //   16: dup
    //   17: aload_0
    //   18: new 211	java/net/ServerSocket
    //   21: dup
    //   22: sipush 7777
    //   25: invokespecial 214	java/net/ServerSocket:<init>	(I)V
    //   28: invokespecial 217	org/jivesoftware/smackx/filetransfer/Socks5TransferNegotiatorManager$ProxyProcess:<init>	(Lorg/jivesoftware/smackx/filetransfer/Socks5TransferNegotiatorManager;Ljava/net/ServerSocket;)V
    //   31: putstatic 209	org/jivesoftware/smackx/filetransfer/Socks5TransferNegotiatorManager:proxyProcess	Lorg/jivesoftware/smackx/filetransfer/Socks5TransferNegotiatorManager$ProxyProcess;
    //   34: getstatic 209	org/jivesoftware/smackx/filetransfer/Socks5TransferNegotiatorManager:proxyProcess	Lorg/jivesoftware/smackx/filetransfer/Socks5TransferNegotiatorManager$ProxyProcess;
    //   37: invokevirtual 220	org/jivesoftware/smackx/filetransfer/Socks5TransferNegotiatorManager$ProxyProcess:start	()V
    //   40: aload_1
    //   41: monitorexit
    //   42: getstatic 209	org/jivesoftware/smackx/filetransfer/Socks5TransferNegotiatorManager:proxyProcess	Lorg/jivesoftware/smackx/filetransfer/Socks5TransferNegotiatorManager$ProxyProcess;
    //   45: invokevirtual 222	org/jivesoftware/smackx/filetransfer/Socks5TransferNegotiatorManager$ProxyProcess:addTransfer	()V
    //   48: getstatic 209	org/jivesoftware/smackx/filetransfer/Socks5TransferNegotiatorManager:proxyProcess	Lorg/jivesoftware/smackx/filetransfer/Socks5TransferNegotiatorManager$ProxyProcess;
    //   51: areturn
    //   52: astore_2
    //   53: aload_1
    //   54: monitorexit
    //   55: aload_2
    //   56: athrow
    //
    // Exception table:
    //   from	to	target	type
    //   7	42	52	finally
    //   53	55	52	finally
  }

  public void cleanup()
  {
    synchronized (this.processLock)
    {
      if (proxyProcess != null)
      {
        proxyProcess.stop();
        proxyProcess = null;
      }
      return;
    }
  }

  public StreamNegotiator createNegotiator()
  {
    return new Socks5TransferNegotiator(this, this.connection);
  }

  public int getConnectionFailures(String paramString)
  {
    int i;
    Integer localInteger = (Integer)this.addressBlacklist.get(paramString);
    if (localInteger != null)
      i = localInteger.intValue();
    while (true)
    {
      return i;
      i = 0;
    }
  }

  public Collection<Bytestream.StreamHost> getStreamHosts()
  {
    synchronized (this.proxyLock)
    {
      if (this.proxies == null)
        initProxies();
      return Collections.unmodifiableCollection(this.streamHosts);
    }
  }

  public void incrementConnectionFailures(String paramString)
  {
    Integer localInteger2;
    Integer localInteger1 = (Integer)this.addressBlacklist.get(paramString);
    if (localInteger1 == null)
      localInteger2 = Integer.valueOf(1);
    while (true)
    {
      this.addressBlacklist.put(paramString, localInteger2);
      return;
      localInteger2 = Integer.valueOf(1 + localInteger1.intValue());
    }
  }

  public void removeTransfer()
  {
    if (proxyProcess == null);
    while (true)
    {
      return;
      proxyProcess.removeTransfer();
    }
  }

  class ProxyProcess
  implements Runnable
  {
    private final Map<String, Socket> connectionMap = new HashMap();
    private boolean done = false;
    private final ServerSocket listeningSocket;
    private Thread thread;
    private int transfers;

    ProxyProcess(, ServerSocket paramServerSocket)
    {
      this.thread = new Thread(this, "File Transfer Connection Listener");
      this.listeningSocket = paramServerSocket;
    }

    private String establishSocks5UploadConnection()
      throws XMPPException, IOException
    {
      int k;
      int i1;
      DataOutputStream localDataOutputStream = new DataOutputStream(paramSocket.getOutputStream());
      DataInputStream localDataInputStream = new DataInputStream(paramSocket.getInputStream());
      if (localDataInputStream.read() != 5)
        throw new XMPPException("Only SOCKS5 supported");
      int i = localDataInputStream.read();
      int[] arrayOfInt = new int[i];
      int j = 0;
      while (true)
      {
        if (j >= i)
        {
          k = -1;
          int l = arrayOfInt.length;
          i1 = 0;
          if (i1 < l)
            break;
          if (k == 0)
            break label142;
          throw new XMPPException("Authentication method not supported");
        }
        arrayOfInt[j] = localDataInputStream.read();
        ++j;
      }
      if (arrayOfInt[i1] == 0)
        k = 0;
      while (true)
      {
        while (true)
        {
          if (k == 0);
          ++i1;
        }
        k = -1;
      }
      label142: byte[] arrayOfByte1 = new byte[2];
      arrayOfByte1[0] = 5;
      arrayOfByte1[1] = 0;
      localDataOutputStream.write(arrayOfByte1);
      String str = Socks5TransferNegotiator.createIncomingSocks5Message(localDataInputStream);
      byte[] arrayOfByte2 = Socks5TransferNegotiator.createOutgoingSocks5Message(0, str);
      if (!(paramSocket.isConnected()))
        throw new XMPPException("Socket closed by remote user");
      localDataOutputStream.write(arrayOfByte2);
      return str;
    }

    // ERROR //
    public void addTransfer()
    {
      // Byte code:
      //   0: aload_0
      //   1: monitorenter
      //   2: aload_0
      //   3: getfield 111	org/jivesoftware/smackx/filetransfer/Socks5TransferNegotiatorManager$ProxyProcess:transfers	I
      //   6: bipush 255
      //   8: if_icmpne +15 -> 23
      //   11: aload_0
      //   12: iconst_1
      //   13: putfield 111	org/jivesoftware/smackx/filetransfer/Socks5TransferNegotiatorManager$ProxyProcess:transfers	I
      //   16: aload_0
      //   17: invokevirtual 114	java/lang/Object:notify	()V
      //   20: aload_0
      //   21: monitorexit
      //   22: return
      //   23: aload_0
      //   24: iconst_1
      //   25: aload_0
      //   26: getfield 111	org/jivesoftware/smackx/filetransfer/Socks5TransferNegotiatorManager$ProxyProcess:transfers	I
      //   29: iadd
      //   30: putfield 111	org/jivesoftware/smackx/filetransfer/Socks5TransferNegotiatorManager$ProxyProcess:transfers	I
      //   33: goto -13 -> 20
      //   36: astore_1
      //   37: aload_0
      //   38: monitorexit
      //   39: aload_1
      //   40: athrow
      //
      // Exception table:
      //   from	to	target	type
      //   2	39	36	finally
    }

    public int getPort()
    {
      return this.listeningSocket.getLocalPort();
    }

    public Socket getSocket()
    {
      synchronized (this.connectionMap)
      {
        Socket localSocket = (Socket)this.connectionMap.get(paramString);
        return localSocket;
      }
    }

    public void removeTransfer()
    {
      monitorenter;
      try
      {
        this.transfers -= 1;
        monitorexit;
        return;
      }
      finally
      {
        localObject = finally;
        monitorexit;
        throw localObject;
      }
    }

    // ERROR //
    public void run()
    {
      // Byte code:
      //   0: aload_0
      //   1: getfield 47	org/jivesoftware/smackx/filetransfer/Socks5TransferNegotiatorManager$ProxyProcess:listeningSocket	Ljava/net/ServerSocket;
      //   4: sipush 10000
      //   7: invokevirtual 140	java/net/ServerSocket:setSoTimeout	(I)V
      //   10: aload_0
      //   11: getfield 36	org/jivesoftware/smackx/filetransfer/Socks5TransferNegotiatorManager$ProxyProcess:done	Z
      //   14: istore 5
      //   16: iload 5
      //   18: ifeq +31 -> 49
      //   21: aload_0
      //   22: getfield 47	org/jivesoftware/smackx/filetransfer/Socks5TransferNegotiatorManager$ProxyProcess:listeningSocket	Ljava/net/ServerSocket;
      //   25: invokevirtual 143	java/net/ServerSocket:close	()V
      //   28: return
      //   29: astore_3
      //   30: aload_3
      //   31: invokevirtual 146	java/net/SocketException:printStackTrace	()V
      //   34: aload_0
      //   35: getfield 47	org/jivesoftware/smackx/filetransfer/Socks5TransferNegotiatorManager$ProxyProcess:listeningSocket	Ljava/net/ServerSocket;
      //   38: invokevirtual 143	java/net/ServerSocket:close	()V
      //   41: goto -13 -> 28
      //   44: astore 4
      //   46: goto -18 -> 28
      //   49: aconst_null
      //   50: astore 6
      //   52: aload_0
      //   53: monitorenter
      //   54: aload_0
      //   55: getfield 111	org/jivesoftware/smackx/filetransfer/Socks5TransferNegotiatorManager$ProxyProcess:transfers	I
      //   58: ifgt +10 -> 68
      //   61: aload_0
      //   62: getfield 36	org/jivesoftware/smackx/filetransfer/Socks5TransferNegotiatorManager$ProxyProcess:done	Z
      //   65: ifeq +92 -> 157
      //   68: aload_0
      //   69: monitorexit
      //   70: aload_0
      //   71: getfield 36	org/jivesoftware/smackx/filetransfer/Socks5TransferNegotiatorManager$ProxyProcess:done	Z
      //   74: istore 8
      //   76: iload 8
      //   78: ifne -57 -> 21
      //   81: aload_0
      //   82: getfield 47	org/jivesoftware/smackx/filetransfer/Socks5TransferNegotiatorManager$ProxyProcess:listeningSocket	Ljava/net/ServerSocket;
      //   85: astore 13
      //   87: aload 13
      //   89: monitorenter
      //   90: aload_0
      //   91: getfield 47	org/jivesoftware/smackx/filetransfer/Socks5TransferNegotiatorManager$ProxyProcess:listeningSocket	Ljava/net/ServerSocket;
      //   94: invokevirtual 150	java/net/ServerSocket:accept	()Ljava/net/Socket;
      //   97: astore 6
      //   99: aload 13
      //   101: monitorexit
      //   102: aload 6
      //   104: ifnull -94 -> 10
      //   107: aload_0
      //   108: aload 6
      //   110: invokespecial 152	org/jivesoftware/smackx/filetransfer/Socks5TransferNegotiatorManager$ProxyProcess:establishSocks5UploadConnection	(Ljava/net/Socket;)Ljava/lang/String;
      //   113: astore 15
      //   115: aload_0
      //   116: getfield 34	org/jivesoftware/smackx/filetransfer/Socks5TransferNegotiatorManager$ProxyProcess:connectionMap	Ljava/util/Map;
      //   119: astore 16
      //   121: aload 16
      //   123: monitorenter
      //   124: aload_0
      //   125: getfield 34	org/jivesoftware/smackx/filetransfer/Socks5TransferNegotiatorManager$ProxyProcess:connectionMap	Ljava/util/Map;
      //   128: aload 15
      //   130: aload 6
      //   132: invokeinterface 156 3 0
      //   137: pop
      //   138: aload 16
      //   140: monitorexit
      //   141: goto -131 -> 10
      //   144: astore 17
      //   146: aload 16
      //   148: monitorexit
      //   149: aload 17
      //   151: athrow
      //   152: astore 12
      //   154: goto -144 -> 10
      //   157: aload_0
      //   158: bipush 255
      //   160: putfield 111	org/jivesoftware/smackx/filetransfer/Socks5TransferNegotiatorManager$ProxyProcess:transfers	I
      //   163: aload_0
      //   164: invokevirtual 159	java/lang/Object:wait	()V
      //   167: goto -113 -> 54
      //   170: astore 20
      //   172: goto -118 -> 54
      //   175: astore 7
      //   177: aload_0
      //   178: monitorexit
      //   179: aload 7
      //   181: athrow
      //   182: astore_1
      //   183: aload_0
      //   184: getfield 47	org/jivesoftware/smackx/filetransfer/Socks5TransferNegotiatorManager$ProxyProcess:listeningSocket	Ljava/net/ServerSocket;
      //   187: invokevirtual 143	java/net/ServerSocket:close	()V
      //   190: aload_1
      //   191: athrow
      //   192: astore 14
      //   194: aload 13
      //   196: monitorexit
      //   197: aload 14
      //   199: athrow
      //   200: astore 11
      //   202: goto -192 -> 10
      //   205: astore 9
      //   207: aload 9
      //   209: invokevirtual 160	XMPPException:printStackTrace	()V
      //   212: aload 6
      //   214: invokevirtual 161	java/net/Socket:close	()V
      //   217: goto -207 -> 10
      //   220: astore 10
      //   222: goto -212 -> 10
      //   225: astore 19
      //   227: goto -199 -> 28
      //   230: astore_2
      //   231: goto -41 -> 190
      //
      // Exception table:
      //   from	to	target	type
      //   0	10	29	java/net/SocketException
      //   34	41	44	IOException
      //   124	149	144	finally
      //   81	90	152	java/net/SocketTimeoutException
      //   107	124	152	java/net/SocketTimeoutException
      //   149	152	152	java/net/SocketTimeoutException
      //   197	200	152	java/net/SocketTimeoutException
      //   163	167	170	java/lang/InterruptedException
      //   54	70	175	finally
      //   157	163	175	finally
      //   163	167	175	finally
      //   177	179	175	finally
      //   0	10	182	finally
      //   10	16	182	finally
      //   30	34	182	finally
      //   52	54	182	finally
      //   70	76	182	finally
      //   81	90	182	finally
      //   107	124	182	finally
      //   149	152	182	finally
      //   179	182	182	finally
      //   197	200	182	finally
      //   207	212	182	finally
      //   212	217	182	finally
      //   90	102	192	finally
      //   194	197	192	finally
      //   81	90	200	IOException
      //   107	124	200	IOException
      //   149	152	200	IOException
      //   197	200	200	IOException
      //   81	90	205	XMPPException
      //   107	124	205	XMPPException
      //   149	152	205	XMPPException
      //   197	200	205	XMPPException
      //   212	217	220	IOException
      //   21	28	225	IOException
      //   183	190	230	IOException
    }

    public void start()
    {
      this.thread.start();
    }

    public void stop()
    {
      ???.done = true;
      monitorenter;
      try
      {
        monitorexit;
      }
      finally
      {
        ServerSocket localServerSocket;
        synchronized (???.listeningSocket)
        {
          ???.listeningSocket.notify();
          monitorexit;
          return;
          localObject1 = finally;
          throw localObject1;
        }
      }
    }
  }
}